/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package digitaldreamers.games.ddmonsters.servers.gameserver.components;

import digitaldreamers.games.ddmonsters.servers.gameserver.components.DuelCellComponent.Coordinates;
import java.util.HashMap;
import java.util.Map.Entry;

/**
 *
 * @author DaoLe
 */
public class DuelFieldComponent {
    
    // <editor-fold defaultstate="collapsed" desc="Constants">
    private static final int NUMBER_OF_ROWS = 7;
    private static final int NUMBER_OF_COLUMNS = 5;
    private static final int ROOM_MASTER_SUMMON_ROW_INDEX = 0;
    private static final int ROOM_GUEST_SUMMON_ROW_INDEX = NUMBER_OF_ROWS - 1;
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Member variables">
    private int m_iFieldType;
    private PlayerComponent m_RoomMaster;
    private PlayerComponent m_RoomGuest;
    private DuelCellComponent[][] m_Cells;
    private HashMap<PlayerComponent, HashMap<MonsterCardComponent, DuelCellComponent>> m_PlayersMonstersCellsMap;
    // </editor-fold>
    
    public MonsterCardComponent getMyMonsterOnField(PlayerComponent player, int iCoordinateX, int iCoordinateY) {
        Coordinates coordinates = new Coordinates(iCoordinateX, iCoordinateY);
        if(player == m_RoomGuest) {
            reverseCoordinates(coordinates);
        }
        MonsterCardComponent monsterCard = null;
        HashMap<MonsterCardComponent, DuelCellComponent> monstersCells = m_PlayersMonstersCellsMap.get(player);
        if(monstersCells != null) {
            for (Entry<MonsterCardComponent, DuelCellComponent> e : monstersCells.entrySet()) {
                DuelCellComponent cell = e.getValue();
                Coordinates cellCoordinates = cell.getCoordinates();
                if(Coordinates.compareCoordinates(coordinates, cellCoordinates)) {
                    monsterCard = e.getKey();
                    break;
                }
            }
        }
        return monsterCard;
    }
    
    // <editor-fold defaultstate="collapsed" desc="Constructors">
    public DuelFieldComponent(int iFieldType, PlayerComponent roomMaster, PlayerComponent roomGuest) {
        m_iFieldType = iFieldType;
        m_RoomMaster = roomMaster;
        m_RoomGuest = roomGuest;
        HashMap<MonsterCardComponent, DuelCellComponent> roomMasterMonstersCells = new HashMap();
        HashMap<MonsterCardComponent, DuelCellComponent> roomGuestMonstersCells = new HashMap();
        m_PlayersMonstersCellsMap = new HashMap();
        m_PlayersMonstersCellsMap.put(roomMaster, roomMasterMonstersCells);
        m_PlayersMonstersCellsMap.put(roomGuest, roomGuestMonstersCells);
        loadBattleCells();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Methods">
    
    public static void reverseCoordinates(Coordinates coordinates) {
        coordinates.setX(NUMBER_OF_COLUMNS - 1 - coordinates.getX());
        coordinates.setY(NUMBER_OF_ROWS - 1 - coordinates.getY());
    }
    
    // <editor-fold defaultstate="collapsed" desc="loadBattleCells">
    private void loadBattleCells() {
        m_Cells = new DuelCellComponent[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS];
        for(int x = 0; x < NUMBER_OF_COLUMNS; x++) {
            for(int y = 0; y < NUMBER_OF_ROWS; y++) {
                m_Cells[y][x] = new DuelCellComponent(x, y);
            }
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="canPlayerSummon(PlayerComponent player, int iSummonCoordinateX, int iSummonCoordinateY)">
    private boolean canSetMonsterHere(PlayerComponent player, MonsterCardComponent monsterCard, Coordinates fromCoordinates, Coordinates toCoordinates, boolean bIsSummon) {
        int iFromCoordinateX = fromCoordinates.getX();
        int iFromCoordinateY = fromCoordinates.getY();
        int iToCoordinateX = toCoordinates.getX();
        int iToCoordinateY = toCoordinates.getY();
        if(iToCoordinateX < 0 || iToCoordinateX >= NUMBER_OF_COLUMNS || iToCoordinateY < 0 || iToCoordinateY >= NUMBER_OF_ROWS) {
            return false;
        }
        if(!m_Cells[iToCoordinateY][iToCoordinateX].getMovementState()) {
            return false;
        }
        if(bIsSummon) {
            if(player == m_RoomMaster) {
                if(iToCoordinateY != ROOM_MASTER_SUMMON_ROW_INDEX) {
                    return false;
                }
            }
            else if(player == m_RoomGuest) {
                if(iToCoordinateY != ROOM_GUEST_SUMMON_ROW_INDEX) {
                    return false;
                }
            }
            else {
                return false;
            }
        }
        else {
            int iMovementRange = Math.abs(iToCoordinateX - iFromCoordinateX) + Math.abs(iToCoordinateY - iFromCoordinateY);
            int iMonsterMovementRange = monsterCard.getDuelMovementRange();
            if(iMovementRange > iMonsterMovementRange) {
                return false;
            }
        }
        return true;
    }
    // </editor-fold>
    
    private void putMonsterOnCell(PlayerComponent player, MonsterCardComponent monsterCard, Coordinates fromCoordinates, Coordinates toCoordinates) {
        int iFromX = fromCoordinates.getX();
        int iFromY = fromCoordinates.getY();
        int iToX = toCoordinates.getX();
        int iToY = toCoordinates.getY();
        m_Cells[iFromY][iFromX].setCard(null);
        m_Cells[iToY][iToX].setCard(monsterCard);
        HashMap<MonsterCardComponent, DuelCellComponent> monstersCells = m_PlayersMonstersCellsMap.get(player);
        monstersCells.put(monsterCard, m_Cells[iToY][iToX]);
    }
    
    public boolean summonMonster(PlayerComponent player, MonsterCardComponent monsterCard, int iSummonCoordinateX, int iSummonCoordinateY) {
        boolean bResult = moveMonster(player, monsterCard, iSummonCoordinateX, iSummonCoordinateY, true);
        return bResult;
    }
    
    public boolean moveMonster(PlayerComponent player, MonsterCardComponent monsterCard, int iToCoordinateX, int iToCoordinateY, boolean bIsSummon) {
        int iFromCoordinateX = 0;
        int iFromCoordinateY = 0;
        if(!bIsSummon) {
            HashMap<MonsterCardComponent, DuelCellComponent> monstersCells = m_PlayersMonstersCellsMap.get(player);
            if(monstersCells != null) {
                DuelCellComponent currentCell = monstersCells.get(monsterCard);
                if(currentCell != null) {
                    Coordinates currentCellCoordinates = currentCell.getCoordinates();
                    iFromCoordinateX = currentCellCoordinates.getX();
                    iFromCoordinateY = currentCellCoordinates.getY();
                }
                else {
                    return false;
                }
            }
            else {
                return false;
            }
        }
        Coordinates fromCoordinates = new Coordinates(iFromCoordinateX, iFromCoordinateY);
        Coordinates toCoordinates = new Coordinates(iToCoordinateX, iToCoordinateY);
        if(player == m_RoomGuest) {
            reverseCoordinates(fromCoordinates);
            reverseCoordinates(toCoordinates);
        }
        boolean bResult = canSetMonsterHere(player, monsterCard, fromCoordinates, toCoordinates, bIsSummon);
        if(bResult) {
            putMonsterOnCell(player, monsterCard, fromCoordinates, toCoordinates);
        }
        return bResult;
    }
    // </editor-fold>
}
